﻿/**************************************************************************
创建时间:	2021/1/22 22:03:07    
作	  者:	张存
邮 	  箱:	zhangcunliang@126.com

Copyright (c) zhcun.cn

描	述：
记	录：
    2021.2.26 升级完 Memory 及相关联的包之后 object 不被转换
    2022.8.16 增加将 dataTable 转换key value 的格式
***************************************************************************/
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Reflection;
using System.Text;

namespace ASmile.Tools
{
    /// <summary>
    ///MiniTable 格式，用于传输
    /// </summary>
    public class MiniTable
    {
        /// <summary>
        /// 默认实例
        /// </summary>
        public MiniTable()
        { }
        /// <summary>
        /// 表名称，TableTabe 同步
        /// </summary>
        public string TableName { set; get; }
        /// <summary>
        /// 设置或返回属性信息
        /// </summary>
        public MiniTableColumn[] Columns { set; get; }
        /// <summary>
        /// 设置或返回行数据
        /// </summary>
        public List<List<string>> RowItems { set; get; }
        /// <summary>
        /// 返回行数量
        /// </summary>
        public int RowCount { get { return RowItems?.Count ?? 0; } }
        /// <summary>
        /// 分页查询时返回总行数
        /// </summary>
        public int RowTotal { set; get; }
        /// <summary>
        /// 返回列数量
        /// </summary>
        public int ColumnCount { get { return Columns?.Length ?? 0; } }
        /// <summary>
        /// 根据 DataTable 创建 MiniTable
        /// </summary>
        public static MiniTable Create(DataTable dt)
        {
            MiniTable table = new MiniTable();
            if (dt == null || dt.Rows.Count == 0 || dt.Columns.Count == 0) return table;
            table.TableName = dt.TableName;

            table.Columns = new MiniTableColumn[dt.Columns.Count];
            for (int i = 0; i < dt.Columns.Count; i++)
            {
                var col = dt.Columns[i];
                table.Columns[i] = new MiniTableColumn
                {
                    Name = col.ColumnName,
                    DataType = col.DataType.ToString()
                };
            }
            table.RowItems = new List<List<string>>();

            for (int i = 0; i < dt.Rows.Count; i++)
            {
                List<string> rowItem = new List<string>();
                for (int j = 0; j < table.ColumnCount; j++)
                {
                    var val = dt.Rows[i][j];
                    if (val == null || val == DBNull.Value)
                    {
                        rowItem.Add(null);
                        continue;
                    }
                    rowItem.Add(val.ToString());
                }
                table.RowItems.Add(rowItem);
            }
            return table;
        }
        /// <summary>
        /// 当前对象转换为 DataTable
        /// </summary>
        /// <returns></returns>
        public DataTable ToDataTable()
        {
            DataTable dt = new DataTable();
            dt.TableName = TableName;
            if (ColumnCount == 0 || RowCount == 0) return dt;
            foreach (var item in Columns)
            {
                Type dataType = Type.GetType(item.DataType);
                dt.Columns.Add(new DataColumn
                {
                    ColumnName = item.Name,
                    DataType = dataType
                });
            }
            foreach (List<string> rowItem in RowItems)
            {
                dt.Rows.Add(rowItem.ToArray());
            }
            return dt;
        }
        /// <summary>
        /// 转换为泛型 List
        /// </summary>
        public List<T> ToList<T>() where T : class, new()
        {
            if (ColumnCount == 0 || RowCount == 0) return null;
            List<T> rList = new List<T>();
            PropertyInfo[] pInfos = typeof(T).GetProperties();
            foreach (var rowData in RowItems)
            {
                T obj = new T();
                for (int i = 0; i < Columns.Length; i++)
                {
                    var val = rowData[i];
                    if (val == null) continue;
                    var col = Columns[i];
                    var pInfo = pInfos.FirstOrDefault(s => s.Name == col.Name);
                    if (pInfo == null) continue;
                    var newVal = Convert.ChangeType(val, Type.GetType(col.DataType));
                    pInfo.SetValue(obj, newVal, null);
                }
                rList.Add(obj);
            }
            return rList;
        }
        /// <summary>
        /// 转换键值对的字典形式
        /// </summary>
        public List<Dictionary<string, string>> ToKV()
        {
            if (ColumnCount == 0 || RowCount == 0) return null;
            var rList = new List<Dictionary<string, string>>();
            foreach (var rowData in RowItems)
            {
                var dataRow = new Dictionary<string, string>();
                for (int i = 0; i < Columns.Length; i++)
                {
                    var val = rowData[i];
                    if (val == null) continue;
                    var col = Columns[i];
                    dataRow[col.Name] = val;
                }
                rList.Add(dataRow);
            }
            return rList;
        }
    }
    /// <summary>
    /// MiniTable 列信息
    /// </summary>
    public class MiniTableColumn
    {
        /// <summary>
        /// 列名
        /// </summary>
        public string Name { set; get; }
        /// <summary>
        /// 列类型字符串,由 Type.ToString() 生成
        /// </summary>
        public string DataType { set; get; }
    }
}
